home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / NDK / NDK_3.1 / Examples1 / intuition / relspecial.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-27  |  7.4 KB  |  305 lines

  1. /*
  2.  * relspecial.c - shows special gadget relativity
  3.  *
  4.  * (c) Copyright 1992-1999 Amiga, Inc.  All rights reserved.
  5.  *
  6.  * This software is provided as-is and is subject to change; no warranties
  7.  * are made.  All use is at your own risk.  No liability or responsibility
  8.  * is assumed.
  9.  *
  10.  * Special gadget relativity allows a gadget to arbitrarily resize
  11.  * itself whenever the window changes size.  This is a complete superset
  12.  * of the functionality of the old GRELWIDTH, GRELRIGHT, etc., features.
  13.  * This example shows a subclass of gadgetclass whose imagery comes
  14.  * from frameiclass.  This gadget's property is that it is always half
  15.  * the size of its domain, and centered within it.  That is, it's always
  16.  * half as wide and half as tall as the inner area of its window, and
  17.  * centered within that area.
  18.  */
  19.  
  20. #include <intuition/intuition.h>
  21. #include <intuition/gadgetclass.h>
  22. #include <intuition/imageclass.h>
  23. #include <intuition/cghooks.h>
  24. #include <intuition/classes.h>
  25. #include <intuition/classusr.h>
  26.  
  27. #include <clib/alib_protos.h>
  28. #include <clib/exec_protos.h>
  29. #include <clib/graphics_protos.h>
  30. #include <clib/intuition_protos.h>
  31.  
  32. #include <stdio.h>
  33.  
  34. struct Library *GfxBase = NULL;
  35. struct Library *IntuitionBase = NULL;
  36. struct Window *win = NULL;
  37. struct Gadget *gad = NULL;
  38. Class *specialrelclass = NULL;
  39.  
  40. Class *initSpecialRelClass(void);
  41. ULONG __saveds __asm dispatchSpecialRel( register __a0 Class *cl,
  42.     register __a2 Object *o, register __a1 Msg msg );
  43. void renderSpecialRel( struct Gadget *gad, struct RastPort *rp,
  44.     struct GadgetInfo *gi );
  45. void layoutSpecialRel( struct Gadget *gad, struct GadgetInfo *gi,
  46.     ULONG initial );
  47. LONG handleSpecialRel( struct Gadget *gad, struct gpInput *msg );
  48.  
  49.  
  50. void main(void)
  51. {
  52.     if ( GfxBase = OpenLibrary("graphics.library",39) )
  53.     {
  54.     if ( IntuitionBase = OpenLibrary("intuition.library",39) )
  55.     {
  56.         if ( specialrelclass = initSpecialRelClass() )
  57.         {
  58.         if ( gad = NewObject( specialrelclass, NULL,
  59.             GA_Left, 20,
  60.             GA_Top, 20,
  61.             GA_Width, 20,
  62.             GA_Height, 20,
  63.             GA_RelVerify, TRUE,
  64.             GA_Immediate, TRUE,
  65.             TAG_DONE ) )
  66.         {
  67.             if ( win = OpenWindowTags( NULL,
  68.             WA_Title, "Special Relativity Demo",
  69.             WA_CloseGadget, TRUE,
  70.             WA_DepthGadget, TRUE,
  71.             WA_DragBar, TRUE,
  72.             WA_SizeGadget, TRUE,
  73.             WA_Gadgets, gad,
  74.             WA_Activate, TRUE,
  75.             WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_GADGETDOWN | IDCMP_GADGETUP,
  76.             WA_Width, 150,
  77.             WA_Height, 150,
  78.             WA_MinWidth, 50,
  79.             WA_MinHeight, 50,
  80.             WA_MaxWidth, ~0,
  81.             WA_MaxHeight, ~0,
  82.             WA_NoCareRefresh, TRUE,
  83.             TAG_DONE ) )
  84.             {
  85.             BOOL terminated = FALSE;
  86.             struct IntuiMessage *imsg;
  87.  
  88.             while ( !terminated )
  89.             {
  90.                 Wait( 1 << win->UserPort->mp_SigBit );
  91.                 while ( imsg = (struct IntuiMessage *)GetMsg( win->UserPort ) )
  92.                 {
  93.                 switch ( imsg->Class )
  94.                 {
  95.                 case IDCMP_CLOSEWINDOW:
  96.                     terminated = TRUE;
  97.                     break;
  98.  
  99.                 case IDCMP_GADGETUP:
  100.                     printf("Gadget up\n");
  101.                     break;
  102.  
  103.                 case IDCMP_GADGETDOWN:
  104.                     printf("Gadget down\n");
  105.                     break;
  106.                 }
  107.                 ReplyMsg( (struct Message *)imsg );
  108.                 }
  109.             }
  110.             CloseWindow( win );
  111.             }
  112.             DisposeObject( gad );
  113.         }
  114.         FreeClass( specialrelclass );
  115.         }
  116.         CloseLibrary( IntuitionBase );
  117.     }
  118.     CloseLibrary( GfxBase );
  119.     }
  120. }
  121.  
  122.  
  123. /* initSpecialRelClass()
  124.  *
  125.  * Initialize a simple private subclass of gadgetclass that
  126.  * knows about GM_LAYOUT.
  127.  *
  128.  */
  129.  
  130. Class *initSpecialRelClass( void )
  131. {
  132.     Class *cl;
  133.  
  134.     /* Create a private class: */
  135.     if ( cl = MakeClass( NULL, "gadgetclass", NULL, 0, 0 ) )
  136.     {
  137.     cl->cl_Dispatcher.h_SubEntry = NULL;
  138.     cl->cl_Dispatcher.h_Entry = (HOOKFUNC)dispatchSpecialRel;
  139.     cl->cl_Dispatcher.h_Data = NULL;
  140.     }
  141.     return ( cl );
  142. }
  143.  
  144. /* dispatchSpecialRel()
  145.  *
  146.  * boopsi dispatcher for the special relativity class.
  147.  *
  148.  */
  149.  
  150. ULONG __saveds __asm
  151. dispatchSpecialRel( register __a0 Class *cl,
  152.             register __a2 Object *o,
  153.             register __a1 Msg msg )
  154. {
  155.     ULONG retval = 1;
  156.     Object *newobj;
  157.  
  158.     switch ( msg->MethodID )
  159.     {
  160.     case OM_NEW:
  161.     if ( retval = (ULONG)(newobj = (Object *) DoSuperMethodA( cl, o, msg )) )
  162.     {
  163.         /* Set special relativity */
  164.         ((struct Gadget *)newobj)->Flags |= GFLG_RELSPECIAL;
  165.         /* Attempt to allocate a frame.  If I can't, then
  166.          * delete myself and fail.
  167.          */
  168.         if ( ! ( ((struct Gadget *)newobj)->GadgetRender =
  169.         NewObject( NULL, "frameiclass", TAG_DONE ) ) )
  170.         {
  171.         CoerceMethod( cl, newobj, OM_DISPOSE );
  172.         retval = NULL;
  173.         }
  174.     }
  175.     break;
  176.  
  177.     case GM_LAYOUT:
  178.     layoutSpecialRel( (struct Gadget *)o, ((struct gpLayout *)msg)->gpl_GInfo,
  179.         ((struct gpLayout *)msg)->gpl_Initial );
  180.     break;
  181.  
  182.     case GM_RENDER:
  183.     renderSpecialRel( (struct Gadget *)o, ((struct gpRender *) msg)->gpr_RPort,
  184.         ((struct gpRender *) msg)->gpr_GInfo );
  185.     break;
  186.  
  187.     case GM_GOACTIVE:
  188.     return( GMR_MEACTIVE );
  189.     break;
  190.  
  191.     case GM_HANDLEINPUT:
  192.     retval = handleSpecialRel( (struct Gadget *)o, (struct gpInput *)msg );
  193.     break;
  194.  
  195.     case OM_DISPOSE:
  196.     DisposeObject( ((struct Gadget *)o)->GadgetRender );
  197.     /* fall through to default */
  198.     default:
  199.     retval = (ULONG) DoSuperMethodA( cl, o, msg );
  200.     }
  201.     return( retval );
  202. }
  203.  
  204.  
  205. /* renderSpecialRel()
  206.  *
  207.  * Simple routine to draw my imagery based on my selected state.
  208.  *
  209.  */
  210. void
  211. renderSpecialRel( struct Gadget *gad, struct RastPort *rp, struct GadgetInfo *gi )
  212. {
  213.     DrawImageState( rp, gad->GadgetRender, gad->LeftEdge, gad->TopEdge,
  214.     (gad->Flags & GFLG_SELECTED) ? IDS_SELECTED : IDS_NORMAL,
  215.     gi ? gi->gi_DrInfo : NULL );
  216. }
  217.  
  218.  
  219. /* layoutSpecialRel()
  220.  *
  221.  * Lay myself out based on my domain dimensions.  Refigure my own size,
  222.  * then inform my image of the size change.
  223.  *
  224.  */
  225. void
  226. layoutSpecialRel( struct Gadget *gad, struct GadgetInfo *gi, ULONG initial )
  227. {
  228.     if ( gi->gi_Requester )
  229.     {
  230.     /* Center it within the requester */
  231.     gad->Width = gi->gi_Domain.Width / 2;
  232.     gad->Height = gi->gi_Domain.Height / 2;
  233.     gad->LeftEdge = gad->Width / 2;
  234.     gad->TopEdge = gad->Height / 2;
  235.     }
  236.     else
  237.     {
  238.     /* Center it within the window, after accounting for
  239.      * the window borders
  240.      */
  241.     gad->Width = ( gi->gi_Domain.Width -
  242.         gi->gi_Window->BorderLeft - gi->gi_Window->BorderRight ) / 2;
  243.     gad->Height = ( gi->gi_Domain.Height -
  244.         gi->gi_Window->BorderTop - gi->gi_Window->BorderBottom ) / 2;
  245.     gad->LeftEdge = ( gad->Width / 2 ) + gi->gi_Window->BorderLeft;
  246.     gad->TopEdge = ( gad->Height / 2 ) + gi->gi_Window->BorderTop;
  247.     }
  248.     SetAttrs( gad->GadgetRender,
  249.     IA_Width, gad->Width,
  250.     IA_Height, gad->Height,
  251.     TAG_DONE );
  252. }
  253.  
  254.  
  255. /* handleSpecialRel()
  256.  *
  257.  * Routine to handle input to the gadget.  Behaves like a basic
  258.  * hit-select gadget.
  259.  *
  260.  */
  261. LONG
  262. handleSpecialRel( struct Gadget *gad, struct gpInput *msg )
  263. {
  264.     WORD selected = 0;
  265.     struct RastPort *rp;
  266.     LONG retval = GMR_MEACTIVE;
  267.  
  268.     /* Could send IM_HITTEST to image instead */
  269.     if ( ( msg->gpi_Mouse.X >= 0 ) &&
  270.     ( msg->gpi_Mouse.X < gad->Width ) &&
  271.     ( msg->gpi_Mouse.Y >= 0 ) &&
  272.     ( msg->gpi_Mouse.Y < gad->Height ) )
  273.     {
  274.     selected = GFLG_SELECTED;
  275.     }
  276.  
  277.     if ((msg->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE) &&
  278.     (msg->gpi_IEvent->ie_Code == SELECTUP))
  279.     {
  280.     /* gadgetup, time to go */
  281.     if ( selected )
  282.     {
  283.         retval = GMR_NOREUSE | GMR_VERIFY;
  284.     }
  285.     else
  286.     {
  287.         retval = GMR_NOREUSE;
  288.     }
  289.     /* and unselect the gadget on our way out... */
  290.     selected = 0;
  291.     }
  292.  
  293.     if ( ( gad->Flags & GFLG_SELECTED ) != selected )
  294.     {
  295.     gad->Flags ^= GFLG_SELECTED;
  296.     if ( rp = ObtainGIRPort( msg->gpi_GInfo ) )
  297.     {
  298.         DoMethod( (Object *)gad, GM_RENDER, msg->gpi_GInfo, rp, GREDRAW_UPDATE );
  299.         ReleaseGIRPort( rp );
  300.     }
  301.     }
  302.  
  303.     return( retval );
  304. }
  305.